﻿/**
 *	@author  >> Justin Windle
 *	@link	 >> soulwire.co.uk
 * 
 * 
 */

package  
{
	import com.soulwire.geom.ColourMatrix;
	import com.soulwire.media.MotionTracker;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.ColorMatrixFilter;
	import flash.media.Camera;
	import flash.media.Video;

	public class Main extends Sprite
	{
		
		/*
		========================================================
		| Private Variables                         | Data Type  
		========================================================
		*/
		
		private var _motionTracker:					MotionTracker;
		
		private var _target:						Shape;
		private var _bounds:						Shape;
		private var _output:						Bitmap;
		private var _source:						Bitmap;
		private var _video:							BitmapData;
		private var _matrix:						ColourMatrix;
		
		/*
		========================================================
		| Constructor
		========================================================
		*/
		
		public function Main() 
		{
			/*** SETUP ***/
			
			
			var camW:int = 300;
			var camH:int = 250;

			// Create the camera
			var cam:Camera = Camera.getCamera();
			cam.setMode( camW, camH, stage.frameRate );
			
			// Create a video
			var vid:Video = new Video( camW, camH );
			vid.attachCamera( cam );
			
			// Create the Motion Tracker
			_motionTracker = new MotionTracker( vid );
			
			// We flip the input as we want a mirror image
			_motionTracker.flipInput = true;
			
			
			/*** Create a few things to help us visualise what the MotionTracker is doing... ***/
			
			
			_matrix = new ColourMatrix();
			_matrix.brightness = _motionTracker.brightness;
			_matrix.contrast = _motionTracker.contrast;
			
			// Display the camera input with the same filters (minus the blur) as the MotionTracker is using
			_video = new BitmapData( camW, camH, false, 0 );
			_source = new Bitmap( _video );
			_source.scaleX = -1;
			_source.x = camW;
			_source.filters = [ new ColorMatrixFilter( _matrix.getMatrix() ) ];
			addChild( _source );
			
			// Show the image the MotionTracker is processing and using to track
			_output = new Bitmap( _motionTracker.trackingImage );
			_output.x = camW;
			addChild( _output );
			
			
			// A shape to represent the tracking point
			_target = new Shape();
			_target.graphics.lineStyle( 0, 0xFFFFFF );
			_target.graphics.drawCircle( 0, 0, 10 );
			addChild( _target );
			
			// A box to represent the activity area
			_bounds = new Shape();
			_bounds.x = _output.x;
			_bounds.y = _output.y;
			addChild( _bounds );
			
			// Configure the UI
			blurStep.addEventListener( Event.CHANGE, setValues );
			brightnessStep.addEventListener( Event.CHANGE, setValues );
			contrastStep.addEventListener( Event.CHANGE, setValues );
			areaStep.addEventListener( Event.CHANGE, setValues );
			
			// Get going!
			addEventListener( Event.ENTER_FRAME, track );
		}
		
		/*
		========================================================
		| Event Handlers
		========================================================
		*/
		
		private function track( e:Event ):void
		{
			// Tell the MotionTracker to update itself
			_motionTracker.track();
			
			// Move the target with some easing
			_target.x += ((_motionTracker.x + _bounds.x) - _target.x) / 10;
			_target.y += ((_motionTracker.y + _bounds.y) - _target.y) / 10;
			
			_video.draw( _motionTracker.input );
			
			// If there is enough movement (see the MotionTracker's minArea property) then continue
			if ( !_motionTracker.hasMovement ) return;
			
			// Draw the motion bounds so we can see what the MotionTracker is doing
			_bounds.graphics.clear();
			_bounds.graphics.lineStyle( 0, 0xFFFFFF );
			_bounds.graphics.drawRect( _motionTracker.motionArea.x,
									   _motionTracker.motionArea.y,
									   _motionTracker.motionArea.width,
									   _motionTracker.motionArea.height
										);
		}
		
		private function setValues( e:Event ):void
		{
			switch( e.currentTarget )
			{
				case blurStep :
					_motionTracker.blur = blurStep.value;
				break;
				
				case brightnessStep :
					_motionTracker.brightness = _matrix.brightness = brightnessStep.value;
				break;
				
				case contrastStep :
					_motionTracker.contrast = _matrix.contrast = contrastStep.value;
				break;
				
				case areaStep :
					_motionTracker.minArea = areaStep.value;
				break;
			}
			
			_source.filters = [ new ColorMatrixFilter( _matrix.getMatrix() ) ];
		}
		
	}
	
}
